<?php

/*
 * 支付相关处理
 */

namespace app\home\controller;

use think\Lang;
	use think\Log;

	/**
 * ============================================================================
 * DSMall多用户商城
 * ============================================================================
 * 版权所有 2014-2028 长沙德尚网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.csdeshang.com
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用 .
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 * 控制器
 */
class Payment extends BaseMall {

    public function _initialize() {
        parent::_initialize(); // TODO: Change the autogenerated stub
        Lang::load(APP_PATH . 'home/lang/'.config('default_lang').'/buy.lang.php');
    }

    /**
     * 实物商品订单
     */
    public function real_order() {
        $pay_sn = input('post.pay_sn');
        $payment_code = input('post.payment_code');
        $url = url('Memberorder/index');

        if (!preg_match('/^\d{20}$/', $pay_sn)) {
            $this->error(lang('param_error'), $url);
        }
        $logic_payment = model('payment', 'logic');
        $result = $logic_payment->getPaymentInfo($payment_code);
        if (!$result['code']) {
            $this->error($result['msg'], $url);
        }
        $payment_info = $result['data'];
        //计算所需支付金额等支付单信息
        $result = $logic_payment->getRealOrderInfo($pay_sn, session('member_id'));
        if (!$result['code']) {
            $this->error($result['msg'], $url);
        }
        if ($result['data']['api_paystate'] || empty($result['data']['api_pay_amount'])) {
            $this->error(lang('no_payment_required_this_order'), $url);
        }

        //转到第三方API支付
        $this->_api_pay($result['data'], $payment_info);
    }

    /**
     * 虚拟商品购买
     */
    public function vr_order() {
        $order_sn = input('post.order_sn');
        $payment_code = input('post.payment_code');
        $url = url('Membervrorder/index');

        if (!preg_match('/^\d{20}$/', $order_sn)) {
            $this->error(lang('param_error'));
        }

        $logic_payment = model('payment', 'logic');
        $result = $logic_payment->getPaymentInfo($payment_code);
        if (!$result['code']) {
            $this->error($result['msg'], $url);
        }
        $payment_info = $result['data'];

        //计算所需支付金额等支付单信息
        $result = $logic_payment->getVrOrderInfo($order_sn, session('member_id'));
        if (!$result['code']) {
            $this->error($result['msg'], $url);
        }

        if ($result['data']['order_state'] != ORDER_STATE_NEW || empty($result['data']['api_pay_amount'])) {
            $this->error(lang('no_payment_required_this_order'), $url);
        }

        //转到第三方API支付
        $this->_api_pay($result['data'], $payment_info);
    }

    /**
     * 预存款充值
     */
    public function pd_order() {
        $pdr_sn = input('param.pdr_sn');
        $payment_code = input('param.payment_code');
        $url = url('Predeposit/index');

        if (!preg_match('/^\d{20}$/', $pdr_sn)) {
            $this->error(lang('param_error'), $url);
        }

        $logic_payment = model('payment', 'logic');
        $result = $logic_payment->getPaymentInfo($payment_code);
        if (!$result['code']) {
            $this->error($result['msg'], $url);
        }
        $payment_info = $result['data'];
        $result = $logic_payment->getPdOrderInfo($pdr_sn, session('member_id'));
        if (!$result['code']) {
            $this->error($result['msg'], $url);
        }
        if ($result['data']['pdr_payment_state'] || empty($result['data']['api_pay_amount'])) {
            $this->error(lang('no_payment_required'), $url);
        }

        //转到第三方API支付
        $this->_api_pay($result['data'], $payment_info);
    }

    /**
     * 第三方在线支付接口
     *
     */
    private function _api_pay($order_info, $payment_info) {
        try{
        $payment_api = new $payment_info['payment_code']($payment_info);
        }catch(\Exception $e){
            $this->error($e->getMessage());
        }
        if (in_array($payment_info['payment_code'],array('wxpay_native','allinpay'))) {
            if (!extension_loaded('curl')) {
                $this->error(lang('please_check_system_configuration'));
            }

            if (array_key_exists('order_list', $order_info)) {
                $this->assign('order_list', $order_info['order_list']);
                $this->assign('args', 'buyer_id=' . session('member_id') . '&pay_id=' . $order_info['pay_id']);
            } else {
                $this->assign('order_list', array());
                if ($order_info['order_type'] == 'pd_order') {
                    $this->assign('args', 'buyer_id=' . session('member_id') . '&pdr_sn=' . $order_info['pdr_sn']);
                } else {
                    $this->assign('args', 'buyer_id=' . session('member_id') . '&order_id=' . (isset($order_info['order_id']) ? $order_info['order_id'] : ''));
                }
            }
            $this->assign('api_pay_amount', $order_info['api_pay_amount']);
            try{
            $pay_url=base64_encode(ds_encrypt($payment_api->get_payform($order_info), MD5_KEY));
            }catch(\Exception $e){
                $this->error($e->getMessage());
            }
            
            $this->assign('pay_url', $pay_url);
            $this->assign('nav_list', rkcache('nav', true));
            if($payment_info['payment_code']=='wxpay_native'){
                $pay_method=lang('pay_method_wechat');
            }elseif($payment_info['payment_code']=='allinpay'){
                $paytype=input('param.paytype');
                switch($paytype){
                    case 'W01':
                        $pay_method=lang('pay_method_wechat');
                        break;
                    case 'A01':
                        $pay_method=lang('pay_method_alipay');
                        break;
                    case 'Q01':
                        $pay_method=lang('pay_method_tenpay');
                        break;
                    case 'U01':
                        $pay_method=lang('pay_method_unionpay');
                        break;
                    default:
                        $this->error(lang('please_check_system_configuration'));
                }

            }
            $this->assign('pay_method',$pay_method);
            echo $this->fetch($this->template_dir . 'wxpay');
        } else {
            try{
            $pay_url=$payment_api->get_payform($order_info);
            }catch(\Exception $e){
                $this->error($e->getMessage());
            }
            @header("Location: " . $pay_url);
        }
        exit();
    }
    
    /**
     * 二维码显示(微信扫码支付) 
     */
    public function qrcode() {
        $data = base64_decode(input('data'));
        $data = ds_decrypt($data, MD5_KEY, 30);
        import('qrcode.phpqrcode', EXTEND_PATH);
        \QRcode::png($data);
    }
    /**
     * 扫码支付结果判断
     */
    public function query_state() {
        if (intval(input('param.pay_id')) > 0) {
            $info = model('order')->getOrderpayInfo(array(
                'pay_id' => intval(input('param.pay_id')),
                'buyer_id' => intval(input('param.buyer_id'))
            ));
            exit(json_encode(array(
                'state' => ($info['api_paystate'] == '1'), 'pay_sn' => $info['pay_sn'], 'type' => 'real_order'
            )));
        } elseif (intval(input('param.order_id')) > 0) {
            $info = model('vrorder')->getVrorderInfo(array(
                'order_id' => intval(input('param.order_id')),
                'buyer_id' => intval(input('param.buyer_id'))
            ));
            exit(json_encode(array(
                'state' => ($info['order_state'] == '20'), 'pay_sn' => $info['order_sn'], 'type' => 'vr_order'
            )));
        } else {
            $result = model('payment', 'logic')->getPdOrderInfo(input('param.pdr_sn'), input('param.buyer_id'));
            exit(json_encode(array('state' => ($result['data']['pdr_payment_state'] == '1'), 'pdr_sn' => $result['data']['pdr_sn'], 'type' => 'pd_order')));
        }
    }

    /**
     * 
     * @param type $payment_code  共用回调方法
     * @param type $show_code  实际支付方式名称
     */
    public function notify($payment_code,$show_code='') {
	   Log::error("支付回调参数".json_encode($this->request->param()));
        $logic_payment = model('payment', 'logic');
        $result = $logic_payment->getPaymentInfo($payment_code);
        $payment_info = $result['data'];

        //创建支付接口对象
        $payment_api = new $payment_info['payment_code']($payment_info);

        //对进入的参数进行远程数据判断
        $verify = $payment_api->verify_notify();
        if ($verify['trade_status'] != 1) {
            exit;
        }
        Log::error("支付回调参数".json_encode($verify));
	    $out_trade_no = $verify['out_trade_no']; #内部订单号
	    if(ordermodel($out_trade_no)){
		    if(strpos($payment_code, "alipay") !== false){
			    $this->callback_msg_update($verify, $_POST, 1);
		    }else if(strpos($payment_code, 'wxpay') !== false){
			    $xml   = file_get_contents("php://input");
			    $this->callback_msg_update($verify, $xml, 2);
		    }
	    }

	    $trade_no = $verify['trade_no']; #交易订单号
	    $order_type = $verify['order_type']; #交易类型


	    $update_result = $logic_payment->updateOrder($out_trade_no, $trade_no, $order_type, $show_code?$show_code:$payment_code);
        exit($update_result ? 'success' : 'fail');
    }

	/**
	 * 回调测试
	 */
	public function callback_test()
	{
		$data='';
		$xml='{"gmt_create":"2020-02-14 15:28:56","charset":"utf-8","seller_email":"15157164007@139.com","subject":"\u5145\u503c0.01\u5143","sign":"t3mT1SwaVs8s2ruiUgpfn0OuVpxl9uRUjSG9QOo+77A3rCGBnVIf94D2CG00pecV1JrHAE\/sSR0TcM8sZq1lGgY8WbQ63o6XNzlGeOwFsFk7z78zLHriPOMJ4gAkcla48pRCw7X01nydDxpM5mNdfP2BfHEyGjMEm\/c5ixs8509i9QuaI2XPJpQIRUe1f+tdCTyV6Y5hSBwfYxwKFfiO\/y5eTaLrrh0Y9C+B8PGs6AZY2iJNlQWdK1lyw7oTP357EMkt87ioVti5ImG5qw6d\/bkcWmzq4SYQvc12cHrIKkCOmGGX1GrQ1CDAvtadB0jI3+wXw4jWyuOkKuvvmOBlUw==","buyer_id":"2088422550444736","invoice_amount":"0.01","notify_id":"2020021400222152857044731436605841","fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]","notify_type":"trade_status_sync","trade_status":"TRADE_SUCCESS","receipt_amount":"0.01","app_id":"2021001100624632","buyer_pay_amount":"0.01","sign_type":"RSA2","seller_id":"2088531086231586","gmt_payment":"2020-02-14 15:28:56","notify_time":"2020-02-14 15:31:11","version":"1.0","out_trade_no":"203132020021410151101","total_amount":"0.01","trade_no":"2020021422001444731419906885","auth_app_id":"2021001100624632","buyer_logon_id":"173****0351","point_amount":"0.00"}';
		$xml=json_decode($xml,true);
		$this->callback_msg_update($data, $xml, 1);
	}
	/**
	 * @param $data        数据 字段信息 out_trade_no 自己的  trade_no 微信或者支付宝 返回的的订单号
	 * @param $xml 微信 支付宝原样 返回
	 * @param $up_pay_type 支付类型 1 支付宝 2 微信
	 * @return string
	 */
	private function callback_msg_update($data, $xml, $up_pay_type){
		$data_arr['weixin']  = $xml;//微信参数

		if($up_pay_type == 1){
			//$data_arr['type'] = 'wechat';
			$url = "http://cjj.mbcanfu.com/api/payi/alipay_callback";//vip微信回调
			// $resArr = doCurl($url, 1 ,$data);
			$resArr = doCurl($url, 1, $xml);
			$resArr = json_decode($resArr,true);

		}

		if($up_pay_type == 2){
			//$data_arr['type'] = 'wechat';
			$url = "http://cjj.mbcanfu.com/api/payi/wxcallback";//vip微信回调
			// $resArr = doCurl($url, 1 ,$data);
			$resArr = doCurl($url, 1, $xml);
			$resArr = json_decode($resArr,true);
		}
		Log::error("跳转之后的参数".json_encode($resArr));
		// jsonReturn('断点');
		if(isset($resArr['code']) && $resArr['code'] === 200){
			$this->return_msg($up_pay_type,1);
		}else{
			$this->return_msg($up_pay_type,0);
		}
	}


	/**
	 * 输出xml字符
	 * @param array $data
	 * @return string
	 */
	private function ToXml($data = array())
	{

		$xml = "<xml>";
		foreach ($data as $key=>$val)
		{
			if (is_numeric($val)){
				$xml.="<".$key.">".$val."</".$key.">";
			}else{
				$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
			}
		}
		$xml.="</xml>";
		return $xml;
	}

	/**
	 * 返回信息
	 * @param int $type 1 支付宝 2微信
	 * @param int $status 0 失败 1成功
	 */
	//public function return_msg($type=1,$status=0)
	public function return_msg($type = 1, $status = 0)
	{
		if($type == 1){
			if($status == 1){
				die('success');
			}else{
				die('fail');
			}
		}elseif($type == 2){
			if($status == 1){
				$return['return_code'] = "SUCCESS";
				$return['return_msg'] = "OK";
				$return['sign'] = $this->MakeSign($return);

			}else{
				$return['return_code'] = "FAIL";
				$return['return_msg'] = "失败1";

			}
			echo $this->ToXml($return);
			exit;
		}
	}


    /**
     * 支付接口同步返回路径
     */
    public function alipay_return() {
        $this->return_verify('alipay');
    }

    /**
     * 银联同步通知
     */
    public function unionpay_return() {
        $this->return_verify('unionpay');
    }
    
    
    public function return_verify($payment_code){

        $logic_payment = model('payment', 'logic');
        //取得支付方式
        $result = $logic_payment->getPaymentInfo($payment_code);
        if (!$result['code']) {
            $this->error($result['msg'], 'Memberorder/index');
        }
        $payment_info = $result['data'];

        //创建支付接口对象
        $payment_api = new $payment_info['payment_code']($payment_info);

        //返回参数判断
        $verify = $payment_api->return_verify();
        if (!$verify || $verify['trade_status']=='0') {
            $this->error(lang('payment_data_validation_failed'), 'Memberorder/index');
        }
        $order_type=$verify['order_type'];
        $out_trade_no=$verify['out_trade_no'];
        $order_amount=$verify['total_fee'];
        //支付成功后跳转
        if ($order_type == 'real_order') {
            $pay_ok_url = HOME_SITE_URL . '/buy/pay_ok?pay_sn=' . $out_trade_no . '&pay_amount=' . ds_price_format($order_amount);
        } elseif ($order_type == 'vr_order') {
            $pay_ok_url = HOME_SITE_URL . '/buyvirtual/pay_ok?order_sn=' . $out_trade_no . '&order_amount=' . ds_price_format($order_amount);
        } elseif ($order_type == 'pd_order') {
            $pay_ok_url = HOME_SITE_URL . '/predeposit/index';
        }
        header("Location:$pay_ok_url");
        exit;
    }
    /**
     * 通联异步通知
     */
    public function allinpay_notify(){
        $this->notify('allinpay');
    }
    /**
     * 银联异步通知
     */
    public function unionpay_notify(){
        $this->notify('unionpay');
    }
    /**
     * 微信扫码支付异步通知
     */
    public function wxpay_native_notify() {
        $this->notify('wxpay_native');
    }
     /**
     * 小程序支付异步通知
     */
    public function wxpay_minipro_notify() {
        $this->notify('wxpay_native','wxpay_minipro');
    }
     /**
     * 微信支付支付异步通知
     */
    public function wxpay_jsapi_notify() {
        $this->notify('wxpay_native','wxpay_jsapi');
    }
    /**
     * 微信H5支付异步通知
     */
    public function wxpay_h5_notify() {
        $this->notify('wxpay_native','wxpay_h5');
    }
    /**
     * 微信APP支付异步通知
     */
    public function wxpay_app_notify() {
        $this->notify('wxpay_native','wxpay_app');
    }
    /**
     * 通知处理(支付宝异步对账)
     */
    public function alipay_notify() {
        $this->notify('alipay');
    }
    /**
     * 支付宝APP支付异步通知
     */
    public function alipay_app_notify() {
        $this->notify('alipay_app');
    }
    /**
     * 支付宝wap支付异步通知
     */
    public function alipay_h5_notify() {
        $this->notify('alipay','alipay_h5');
    }
    

}

?>
